
package ga;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Timetable {

    public Timetable() {
    } 
    
    public Timetable(Graph graph) {
        this.graph = graph;
        ids = graph.getStreetsList();
        streets = graph.getStreetsList();
    }

    public void printStreets() {
        for (int i = 0; i < ids.size(); i++) {
            System.out.println(ids.get(i).getV1() + "-" + ids.get(i).getV2());
        }
    }

    public boolean mergeIntervals(Pair p1, Pair p2) {
        //System.out.println("**********" + p1.getV2() + " " + p2.getV1());
        if (p1.getV2() >= p2.getV1()) {
            return true;
        }
        return false;
    }

    public void mergeTimetable() {
        ArrayList<ArrayList<Pair>> copy = timetable;
        for (int i = 0; i < copy.size(); i++) {
            for (int j = 0; j < copy.get(i).size() - 1; j++) {
                Pair p1 = copy.get(i).get(j);
                Pair p2 = copy.get(i).get(j+1);
                //System.out.println("****edge: " +  p1.getV1() + "->" + p1.getV2() + "  " + p2.getV1() + "->" + p2.getV2());

                if(p1.getV2() >= p2.getV1()){
                //if (mergeIntervals(copy.get(i).get(j), copy.get(i).get(j + 1))) {
                    Pair p = new Pair(copy.get(i).get(j).getV1(), copy.get(i).get(j + 1).getV2());
                    
                    timetable.get(i).remove(j+1);
                    timetable.get(i).remove(j);

                    timetable.get(i).add(j, p);

                }
            }
        }
        System.out.println(printTimetable());
    }

    public void sortTimetable() {
        for (int i = 0; i < timetable.size(); i++) {
            Collections.sort(timetable.get(i), new PairComparator());
        }
    }

    public String printTimetable() {
        String res = "";
        System.out.println("timetable size: " + timetable.size());
        for (int i = 0; i < ids.size(); i++) {
            res = res + "edge: " + Integer.toString(ids.get(i).getV1()) + " -> " + Integer.toString(ids.get(i).getV2());
            for (int j = 0; j < timetable.get(i).size(); j++) {
                res = res + " " + Integer.toString(timetable.get(i).get(j).getV1()) + "-" + Integer.toString(timetable.get(i).get(j).getV2());
            }
            res = res + "\n";
        }
        return res;
    }

    private void initialiseTimetable() {
        for (int i = 0; i < streets.size(); i++) {
            timetable.add(new ArrayList<Pair>());
        }
    }

    public void fillTimetableForIndividuum(Individuum ind) {
        initialiseTimetable();
        List<Path> temp = ind.getPaths();
        //System.out.println("res: " + temp.size());
        for (int i = 0; i < temp.size(); i++) {
            Path p = temp.get(i);
            int weight = 0;//==time
            for (int j = 0; j < p.getPath().size() - 1; j++) {
                //1.
                int from = p.getVertex(j);
                int to = p.getVertex(j + 1);
                int currWeight = graph.getEdgeWeight(from, to);
                // streets
                int streetId = findStreet(from, to);
                Pair t = new Pair(weight, weight + currWeight);
                ArrayList<Pair> newList = timetable.get(streetId);
                newList.add(t);
                timetable.set(streetId, newList);//там ArrayList
                weight = weight + currWeight;
            }
        }
    }

    private int findStreet(int from, int to) {
        for (int i = 0; i < streets.size(); i++) {
            if (streets.get(i).getV1() == from && streets.get(i).getV2() == to) {
                return i;
            }
        }
        return 0;
    }

    public int getMaxEndElement() {
        int maxElement = 0;
        for (int i = 0; i < timetable.size(); i++) {
            int currMaxElementIndex = timetable.get(i).size();
            if (currMaxElementIndex > 0) {
                int currMaxElement = timetable.get(i).get(currMaxElementIndex - 1).getV2();
                if (currMaxElement > maxElement) {
                    maxElement = currMaxElement;
                }
            }
        }
        return maxElement;
    }

    public int countOutsideIntervals(int i) {
        int maxElement = getMaxEndElement();
        int intervalsCount = timetable.get(i).size() - 1;
        if (timetable.get(i).size() > 0) {
            if (timetable.get(i).get(0).getV1() > 0) {
                intervalsCount++;
            }
            int index = timetable.get(i).size() - 1;
            if (timetable.get(i).get(index).getV2() < maxElement) {
                intervalsCount++;
            }
        }
        return intervalsCount;
    }

    public int countTimeOutsideIntervals(int i) {//for path
        int maxElement = getMaxEndElement();
        ArrayList<Pair> temp = timetable.get(i);
        for (int j = 0; j < temp.size(); j++) {
            maxElement = maxElement - temp.get(j).getV2() + temp.get(j).getV1();
        }
        return maxElement;
    }

    public ArrayList<ArrayList<Pair>> getTimetable() {
        return timetable;
    }
    
    public int getTimetableSize(){
    
        int res = 0;
        for(int i = 0; i < timetable.size(); i++){
            res = res + timetable.get(i).size();
        }
        return res;
    }
    
    private Graph graph;
    private ArrayList<ArrayList<Pair>> timetable = new ArrayList<ArrayList<Pair>>();
    private ArrayList<Pair> streets = new ArrayList<Pair>();
    private ArrayList<Pair> ids = new ArrayList<Pair>();
}
